package com.note.app.service.impl;

import com.note.app.document.NoteContent;
import com.note.app.document.NoteSearchDocument;
import com.note.app.dto.SearchRequestDTO;
import com.note.app.dto.SearchResultDTO;
import com.note.app.mapper.NoteSearchMapper;
import com.note.app.mapper.TagMapper;
import com.note.app.repository.NoteContentRepository;
import com.note.app.service.SearchService;
import com.note.common.domain.Note;
import com.note.common.vo.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 搜索服务实现 - EasyES版本
 */
@Slf4j
@Service("searchServiceImpl")
public class SearchServiceImpl implements SearchService {

    @Autowired
    private NoteSearchMapper noteSearchMapper;

    @Autowired
    private NoteContentRepository noteContentRepository;

    @Autowired
    private TagMapper tagMapper;

    /**
     * 搜索笔记
     */
    @Override
    public PageResult<SearchResultDTO> searchNotes(Long userId, SearchRequestDTO searchRequest) {
        try {
            // 解码关键词
            String encodedKeyword = searchRequest.getKeyword();
            String decodedKeyword; // 用于保存解码后的关键词

            if (StringUtils.hasText(encodedKeyword)) {
                try {
                    // Base64解码
                    decodedKeyword = new String(Base64.getDecoder().decode(encodedKeyword));
                    log.info("关键词解码成功 - 原始编码: {}, 解码后: {}", encodedKeyword, decodedKeyword);

                    // 去除可能包含的引号
                    decodedKeyword = decodedKeyword.replace("\"", "").trim();
                    log.info("关键词处理后: {}", decodedKeyword);
                } catch (Exception e) {
                    log.error("关键词Base64解码失败, 使用原始值", e);
                    // 解码失败时保持原样
                    decodedKeyword = encodedKeyword;
                }
            } else {
                decodedKeyword = encodedKeyword;
            }

            // 保存最终的关键词，用于Lambda表达式
            final String keyword = decodedKeyword;

            // 使用EasyES构建查询条件
            LambdaEsQueryWrapper<NoteSearchDocument> wrapper = new LambdaEsQueryWrapper<>();
            
            // 用户权限过滤 - 查询自己的笔记或公开笔记
            if (searchRequest.getIncludePublic()) {
                wrapper.and(w -> w.eq(NoteSearchDocument::getUserId, userId)
                                 .or()
                                 .eq(NoteSearchDocument::getIsPublic, true));
            } else {
                wrapper.eq(NoteSearchDocument::getUserId, userId);
            }
            
            // 集合ID过滤
            if (searchRequest.getCollectionId() != null) {
                wrapper.eq(NoteSearchDocument::getCollectionId, searchRequest.getCollectionId());
            }
            
            // 关键词搜索
            if (StringUtils.hasText(keyword)) {
                wrapper.and(w -> {
                    boolean hasCondition = false;
                    
                    if (searchRequest.getSearchTitle()) {
                        w.match(NoteSearchDocument::getTitle, keyword);
                        hasCondition = true;
                    }
                    
                    if (searchRequest.getSearchContent()) {
                        if (hasCondition) {
                            w.or();
                        }
                        w.match(NoteSearchDocument::getContent, keyword);
                        hasCondition = true;
                    }
                    
                    if (searchRequest.getSearchTags() && keyword != null) {
                        if (hasCondition) {
                            w.or();
                        }
                        w.eq(NoteSearchDocument::getTags, keyword);
                    }
                });
            }
            
            // 标签过滤
            if (searchRequest.getIncludeTags() != null && !searchRequest.getIncludeTags().isEmpty()) {
                wrapper.and(w -> {
                    for (int i = 0; i < searchRequest.getIncludeTags().size(); i++) {
                        if (i > 0) {
                            w.or();
                        }
                        w.eq(NoteSearchDocument::getTags, searchRequest.getIncludeTags().get(i));
                    }
                });
            }
            
            // 分页查询
            int pageNum = searchRequest.getPage(); // EasyES页码从0开始
            int pageSize = searchRequest.getSize();
            
            log.info("开始执行EasyES搜索 - 用户ID: {}, 关键词: {}, 页码: {}, 每页条数: {}", 
                    userId, keyword, pageNum, pageSize);
            
            // 执行查询 - 使用selectList + 手动分页处理
            try {
                // 使用selectList方法替代pageQuery
                List<NoteSearchDocument> results = noteSearchMapper.selectList(wrapper);
                log.info("EasyES查询到结果: {}", results.size());
                
                // 手动处理分页
                long total = results.size();
                int fromIndex = pageNum * pageSize;
                int toIndex = Math.min(fromIndex + pageSize, results.size());
                
                List<NoteSearchDocument> pagedList;
                if (fromIndex < total) {
                    pagedList = results.subList(fromIndex, toIndex);
                } else {
                    pagedList = new ArrayList<>();
                }
                
                // 创建分页信息对象
                EsPageInfo<NoteSearchDocument> pageInfo = new EsPageInfo<>();
                pageInfo.setList(pagedList);
                pageInfo.setTotal(total);
                pageInfo.setPageNum(pageNum);
                pageInfo.setPageSize(pageSize);
                pageInfo.setPages((int) Math.ceil((double) total / pageSize));
                
                log.info("手动分页处理结果 - 总记录数: {}, 总页数: {}, 当前页: {}, 当前页记录数: {}", 
                        pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getPageNum(), pagedList.size());
                
                // 转换结果
                List<SearchResultDTO> searchResults = pagedList.stream().map(document -> {
                    SearchResultDTO resultDTO = new SearchResultDTO();

                    resultDTO.setNoteId(document.getNoteId());
                    resultDTO.setUserId(document.getUserId());
                    resultDTO.setCollectionId(document.getCollectionId());
                    resultDTO.setTitle(document.getTitle());
                    resultDTO.setTags(document.getTags());
                    resultDTO.setIsPublic(document.getIsPublic());
                    resultDTO.setCreatedAt(document.getCreatedAt());
                    resultDTO.setUpdatedAt(document.getUpdatedAt());

                    // 处理内容摘要（取前100个字符）
                    if (document.getContent() != null) {
                        String content = document.getContent();
                        resultDTO.setContentSummary(content.length() > 100 ? content.substring(0, 100) + "..." : content);
                    }

                    return resultDTO;
                }).collect(Collectors.toList());

                // 构建分页结果
                return PageResult.of(
                        searchResults,
                        pageInfo.getTotal(),
                        searchRequest.getPage(),
                        searchRequest.getSize());
            } catch (Exception e) {
                log.error("手动分页处理失败: " + e.getMessage(), e);
                // 发生异常时返回空结果
                return PageResult.empty(searchRequest.getPage().longValue(), searchRequest.getSize().longValue());
            }
        } catch (Exception e) {
            log.error("EasyES搜索异常: " + e.getMessage(), e);
            // 发生异常时返回空结果
            return PageResult.empty(searchRequest.getPage().longValue(), searchRequest.getSize().longValue());
        }
    }

    @Override
    public boolean indexNote(Note note) {
        try {
            // 构建索引文档
            NoteSearchDocument document = new NoteSearchDocument();
            document.setId(note.getId().toString());
            document.setNoteId(note.getId());
            document.setUserId(note.getUserId());
            document.setCollectionId(note.getCollectionId());
            document.setTitle(note.getTitle());

            // 从MongoDB获取笔记内容
            if (note.getContentId() != null) {
                Optional<NoteContent> contentOpt = noteContentRepository.findById(note.getContentId());
                if (contentOpt.isPresent()) {
                    document.setContent(contentOpt.get().getContent());
                } else {
                    document.setContent("");
                }
            } else {
                document.setContent("");
            }

            // 获取笔记标签
            List<String> tags = tagMapper.findTagNamesByNoteId(note.getId());
            document.setTags(tags);

            // 设置其他字段
            document.setIsPublic(note.getIsPublic() != null && note.getIsPublic() == 1);
            document.setCreatedAt(note.getCreatedAt());
            document.setUpdatedAt(note.getUpdatedAt());

            // 执行索引操作 - 如果存在则更新，不存在则插入
            int result = noteSearchMapper.insert(document);
            
            log.debug("笔记索引成功: noteId={}, result={}", note.getId(), result);
            return result > 0;
        } catch (Exception e) {
            log.error("笔记索引失败: noteId=" + note.getId(), e);
            return false;
        }
    }

    @Override
    public boolean deleteNoteIndex(Long noteId) {
        try {
            // 执行删除操作
            int result = noteSearchMapper.deleteById(noteId.toString());
            
            log.debug("笔记索引删除成功: noteId={}, result={}", noteId, result);
            return result > 0;
        } catch (Exception e) {
            log.error("笔记索引删除失败: noteId=" + noteId, e);
            return false;
        }
    }
    
    /**
     * 诊断搜索API
     */
    public List<NoteSearchDocument> testSimpleSearch(Long userId) {
        try {
            log.info("执行诊断搜索 - userId: {}", userId);
            
            // 简单查询，查询指定用户的笔记
            LambdaEsQueryWrapper<NoteSearchDocument> wrapper = new LambdaEsQueryWrapper<>();
            wrapper.eq(NoteSearchDocument::getUserId, userId);
            
            List<NoteSearchDocument> results = noteSearchMapper.selectList(wrapper);
            log.info("诊断查询结果数量: {}", results.size());
            
            return results;
        } catch (Exception e) {
            log.error("诊断搜索异常: " + e.getMessage(), e);
            return new ArrayList<>();
        }
    }
}